home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 4
/
FM Towns Free Software Collection 4 - Disc 1.iso
/
t_os
/
wstype
/
source
/
beep.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-18
|
15KB
|
681 lines
/*** [beep.c]
*
* 警告音 関連 (C)ささがわ
*
* For GNU C Compiler (GCC) Version 1.39
*
***/
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>
#include <jstring.h>
#include "graph.h"
#include "mos.h"
#include "window.h"
#include "beep.h"
#include "others.h"
#include "icn.h"
#include "optparse.h"
#define WH_OTHER 0
#define WH_OCTM 1
#define WH_OCTP 10
#define WH_KEY 2
#define WH_VOLM 3
#define WH_VOLP 11
#define WH_VOL 12
#define WH_FILE 4
#define WH_EPCM 5
#define WH_EBEEP 6
#define WH_ENULL 7
#define WH_CAN 8
#define WH_TITLE 9
struct Par {
void *data;
long size;
char name[20];
short oct, ontei, onryo;
};
extern int PAL_Black, PAL_Button;
static int wx, wy;
static int Mode, Pcm;
static struct Par Main, Sub;
static void Move(int, int);
static void Draw_window(void);
static int Where(int, int);
static void Set_name(const unsigned char *, char *);
static int SUB_file(void);
static void errord(void);
static void Draw_oct(void);
static void Draw_ontei(void);
static void Draw_onryo(void);
static void SUB_key(int, int);
static int Where_key(int, int);
static void Draw_mes(int);
static void SUB_oct(int);
static int SUB_oct_sub(int);
static void Draw_volbar(void);
static void SUB_vol(int);
static int SUB_vol_sub(int);
static void SUB_voldr(int, int);
static int Where_vol(int, int);
static void pcm_enable(void);
static int Settings(struct Par *, char *);
int BEP_init(void) {
int r = 0;
char path[90];
if ((Mode = OPT_WarnS(path)) != 1)
return 0;
ICN_mos(1);
Set_name((unsigned char *)path, Main.name);
if (Settings(&Main, path)) {
r = 1;
Mode = 0;
WIND_error(4, path);
}
ICN_mos(0);
return r;
}
void BEP_on(void) {
union REGS regs;
struct SREGS sregs;
switch (Mode) {
case 1:
if (SND_pcm_status(71))
SND_pcm_play_stop(71);
SND_pcm_play(71, Main.ontei, Main.onryo, Main.data);
break;
case 2:
regs.h.ah = 0x02;
int86x(0x9e, ®s, ®s, &sregs);
break;
default:
break;
}
}
int WIND_beep(void) {
int ret = 0;
struct RECT a, b;
wx = 151;
wy = 122;
a.x1 = 319; a.y1 = 259;
a.x2 = 320; a.y2 = 260;
b.x1 = wx; b.y1 = wy;
b.x2 = wx + 337; b.y2 = wy + 236;
afterImage(&a, &b);
if (Mode == 1) {
Pcm = 1;
Sub = Main;
if ((Sub.data = malloc(Sub.size)) == NULL) {
WIND_error(1, NULL);
return -1;
}
memcpy(Sub.data, Main.data, Sub.size);
} else {
Pcm = 0;
Sub.oct = 4;
Sub.ontei = 60;
Sub.onryo = 127;
Sub.name[0] = '\0';
}
Draw_window();
while (!ret) {
char mb;
int mx, my;
CLOCK(0);
if (MOS_rdpos(&mb, &mx, &my), !(mb & 1))
continue;
switch (Where(mx, my)) {
case WH_CAN:
if (Button(wx + 6, wy + 6, wx + 25, wy + 25))
ret = 2;
break;
case WH_FILE:
if (Button(wx + 195, wy + 138, wx + 308, wy + 155)) {
if (SUB_file()) {
Mode = 0;
ret = -1;
}
}
break;
case WH_KEY: SUB_key(mx, my); break;
case WH_OCTM: SUB_oct(1); break;
case WH_OCTP: SUB_oct(0); break;
case WH_VOLM: SUB_vol(1); break;
case WH_VOLP: SUB_vol(0); break;
case WH_VOL: SUB_voldr(mx, my); break;
case WH_EPCM:
if (!Pcm) break;
if (Button(wx + 25, wy + 198, wx + 102, wy + 219)) {
void *p;
p = Main.data;
Main = Sub;
Sub.data = p;
Mode = 1;
ret = 1;
}
break;
case WH_EBEEP:
if (Button(wx + 130, wy + 198, wx + 207, wy + 219)) {
free(Main.data);
Main.data = NULL;
Mode = 2;
ret = 1;
}
break;
case WH_ENULL:
if (Button(wx + 235, wy + 198, wx + 312, wy + 219)) {
free(Main.data);
Main.data = NULL;
Mode = 0;
ret = 1;
}
break;
case WH_TITLE: Move(mx, my); break;
default: while (MOS_rdpos(&mb, &mx, &my), mb & 1); break;
}
}
free(Sub.data);
Sub.data = NULL;
return (ret < 0 ? -1 : 0);
}
static void Move(int mx, int my) {
struct RECT s, w;
w.x1 = wx; w.y1 = wy;
w.x2 = wx + 337; w.y2 = wy + 236;
s.x1 = 0; s.y1 = 40; s.x2 = 639; s.y2 = 463;
if (dragWindow(mx, my, &w, &s, 0, 0)) {
wx = w.x1; wy = w.y1;
MOS_disp(0);
EGB_cls(0);
MOS_disp(1);
Draw_window();
}
}
static void Draw_window(void) {
int i, c;
struct opnwin_t opw;
opw.title = "警 告 音";
opw.x1 = wx;
opw.y1 = wy;
opw.x2 = opw.x1 + 337;
opw.y2 = opw.y1 + 236;
opw.shdw = 1;
opw.canb = 1;
opw.nopt = 0;
opw.wopt = NULL;
opw.expb = 0;
opw.ord = 0;
MOS_disp(0);
drawWindow(&opw);
EGB_str2("オクターブ", wx + 14, wy + 54, PAL_Black);
DrawButton(1, wx + 102, wy + 37, wx + 121, wy + 56);
EGB_box(wx + 121, wy + 37, wx + 140, wy + 56, PAL_Black);
DrawButton(1, wx + 140, wy + 37, wx + 159, wy + 56);
EGB_boxf(wx + 107, wy + 46, wx + 116, wy + 47, PAL_Black, PAL_Black); /* - */
EGB_boxf(wx + 145, wy + 46, wx + 154, wy + 47, PAL_Black, PAL_Black); /* + */
EGB_boxf(wx + 149, wy + 42, wx + 150, wy + 51, PAL_Black, PAL_Black);
Draw_oct();
for (i = 0; i < 7; i++)
EGB_boxf(wx + i * 19 + 20, wy + 67, wx + i * 19 + 39, wy + 156, PAL_Black, 15);
for (i = 0; i < 2; i++)
EGB_boxf(wx + i * 21 + 31, wy + 67, wx + i * 21 + 45, wy + 116, PAL_Black, 8);
for (i = 0; i < 3; i++)
EGB_boxf(wx + i * 21 + 87, wy + 67, wx + i * 21 + 101, wy + 116, PAL_Black, 8);
EGB_str2("音程 No.", wx + 180, wy + 54, PAL_Black);
Draw_ontei();
EGB_str2("音量", wx + 180, wy + 74, PAL_Black);
Draw_onryo();
EGB_str2("音量", wx + 180, wy + 104, PAL_Black);
DrawButton(1, wx + 220, wy + 89, wx + 236, wy + 105);
EGB_boxf(wx + 236, wy + 89, wx + 307, wy + 105, PAL_Black, 6);
DrawButton(1, wx + 307, wy + 89, wx + 323, wy + 105);
EGB_line(wx + 224, wy + 97, wx + 232, wy + 97, PAL_Black); /* - */
EGB_line(wx + 311, wy + 97, wx + 319, wy + 97, PAL_Black); /* + */
EGB_line(wx + 315, wy + 93, wx + 315, wy + 101, PAL_Black);
Draw_volbar();
EGB_str2("サウンドファイル名", wx + 180, wy + 134, PAL_Black);
EGB_box(wx + 194, wy + 137, wx + 309, wy + 156, PAL_Black);
EGB_str2(Sub.name, wx + 204, wy + 154, PAL_Black);
c = Pcm ? PAL_Black : 7;
DrawButton(1, wx + 24, wy + 197, wx + 103, wy + 220);
for (i = 0; i < 2; i++)
EGB_str2("P C M", wx + 32 + i, wy + 216, c);
DrawButton(1, wx + 129, wy + 197, wx + 208, wy + 220);
for (i = 0; i < 2; i++)
EGB_str2("BEEP", wx + 137 + i, wy + 216, PAL_Black);
DrawButton(1, wx + 234, wy + 197, wx + 313, wy + 220);
for (i = 0; i < 2; i++)
EGB_str2(" な し ", wx + 242 + i, wy + 216, PAL_Black);
MOS_disp(1);
Draw_mes(0);
}
static int Where(int x, int y) {
int i, ret = WH_OTHER;
static const short tab[][5] = {
{ 102, 121, 37, 56, WH_OCTM}, { 140, 159, 37, 56, WH_OCTP},
{ 20, 153, 67, 156, WH_KEY}, { 220, 236, 89, 105, WH_VOLM},
{ 236, 307, 89, 105, WH_VOL}, { 307, 323, 89, 105, WH_VOLP},
{ 194, 309, 137, 156, WH_FILE}, { 24, 103, 197, 220, WH_EPCM},
{ 129, 208, 197, 220, WH_EBEEP},{ 234, 313, 197, 220, WH_ENULL},
{ 5, 26, 5, 26, WH_CAN}, { 26, 332, 5, 26, WH_TITLE}
};
x -= wx;
y -= wy;
for (i = 0; i < 12; i++) {
const short *p = tab[i];
if (p[0] < x && x < p[1] && p[2] < y && y < p[3]) {
ret = p[4];
break;
}
}
return ret;
}
static void Set_name(const unsigned char *str, char *buf) { /* ニホンゴ タイオウ */
int i;
unsigned char a[100], *p;
strcpy((char *)a, (const char *)str);
p = a;
while ((p = jstrchr(p, '\\')) != NULL) *(p++) = '\x01b';
for (i = strlen((char *)a) - 1; i > 0; i--) {
if (a[i - 1] == '\x01b' || a[i - 1] == ':')
break;
}
if (strlen((char *)a + i) > 12) {
buf[0] = '\0';
strncat(buf, (char *)a + i, strLE((char *)a + i, 12));
} else
strcpy(buf, (char *)a + i);
strlow(1, (unsigned char *)buf);
}
static int SUB_file(void) {
int ret, res;
char path[85];
MOS_disp(0);
EGB_cls(0);
MOS_disp(1);
res = WIND_filesel("サウンドファイル", path);
MOS_disp(0);
EGB_cls(0);
MOS_disp(1);
switch (res) {
case 1:
ret = 0;
if (SND_pcm_status(71))
SND_pcm_play_stop(71);
Set_name((unsigned char *)path, Sub.name);
Draw_window();
ICN_mos(1);
if (Settings(&Sub, path)) {
ICN_mos(0);
errord();
break;
}
MOS_disp(0);
Draw_oct();
Draw_ontei();
MOS_disp(1);
pcm_enable();
ICN_mos(0);
break;
case -1: ret = -1; break;
default:
Draw_window();
ret = 0;
break;
}
return ret;
}
static void errord(void) {
int i;
Draw_mes(1);
MOS_disp(0);
for (i = 0; i < 2; i++)
EGB_str2("P C M", wx + 32 + i, wy + 216, 7);
MOS_disp(1);
Pcm = 0;
return;
}
static void pcm_enable(void) {
int i;
Draw_mes(0);
MOS_disp(0);
for (i = 0; i < 2; i++)
EGB_str2("P C M", wx + 32 + i, wy + 216, PAL_Black);
MOS_disp(1);
Pcm = 1;
return;
}
static void Draw_oct(void) {
unsigned char buf[5];
unsigned short code;
code = Sub.oct + 0x824f;
buf[0] = (code >> 8) & 0xff;
buf[1] = code & 0xff;
buf[2] = '\0';
EGB_str3((char *)buf, wx + 123, wy + 54, PAL_Black, 7);
}
static void Draw_ontei(void) {
char buf[5];
sprintf(buf, "%3d", Sub.ontei);
EGB_str3(buf, wx + 252, wy + 54, PAL_Black, 7);
}
static void Draw_onryo(void) {
char buf[5];
sprintf(buf, "%3d", Sub.onryo);
EGB_str3(buf, wx + 252, wy + 74, PAL_Black, 7);
}
static void Draw_volbar(void) {
int i;
i = wx + Sub.onryo * 55 / 127 + 244;
if (i - 7 > wx + 237)
EGB_boxf(wx + 237, wy + 90, i - 8, wy + 104, 6, 6);
DrawButton(0, i - 7, wy + 90, i + 7, wy + 104);
if (i + 7 < wx + 306)
EGB_boxf(i + 8, wy + 90, wx + 306, wy + 104, 6, 6);
}
static void SUB_key(int x, int y) {
int wh, d, fl;
char mb;
if (!Pcm) return;
ICN_mos(2);
wh = Where_key(x, y);
Sub.ontei = (Sub.oct - 1) * 12 + 24 + wh;
Draw_ontei();
if (SND_pcm_mode_set(71))
SND_pcm_play_stop(71);
switch (SND_pcm_play(71, Sub.ontei, Sub.onryo, Sub.data)) {
case 6:
case 8:
case 9: Draw_mes(2); break;
case 11: Draw_mes(3); break;
default: Draw_mes(0); break;
}
fl = 1;
while (MOS_rdpos(&mb, &d, &d), mb & 1) {
if (fl && !SND_pcm_status(71)) {
ICN_mos(0);
fl = 0;
}
}
ICN_mos(0);
}
static int Where_key(int x, int y) {
int i;
x -= (wx + 20);
y -= (wy + 67);
for (i = 0; i < 2; i++) {
if (i * 21 + 11 < x && x < i * 21 + 25 && 0 < y && y < 49)
return (i * 2 + 1);
}
for (i = 0; i < 3; i++) {
if (i * 21 + 67 < x && x < i * 21 + 81 && 0 < y && y < 49)
return (i * 2 + 6);
}
for (i = 0; i < 3; i++) {
if (i * 19 < x && x < (i + 1) * 19 && 0 < y && y < 89)
return (i * 2);
}
for (i = 0; i < 4; i++) {
if (i * 19 + 57 < x && x < (i + 1) * 19 + 57 && 0 < y && y < 89)
return (i * 2 + 5);
}
return -1;
}
static void Draw_mes(int no) {
int i;
static const char mes[][38] = {
"上記の設定は、PCMでのみ有効です",
"サウンドの読み込みに失敗しました",
"サウンドデータに異常があります",
};
if (no < 0 || 2 < no)
return;
i = wx + 6 + (326 - strlen(mes[no]) * 8) / 2;
MOS_disp(0);
EGB_boxf(wx + 6, wy + 167, i - 1, wy + 186, 7, 7);
EGB_str3(mes[no], i, wy + 184, PAL_Black, 7);
EGB_boxf(i + strlen(mes[no]) * 8, wy + 167, wx + 331, wy + 186, 7, 7);
MOS_disp(1);
}
static void SUB_oct(int m) {
int flpush = 1, fllast;
int mx, my, lx, ly;
char mb;
lx = wx + (m ? 103 : 141);
ly = wy + 38;
EGB_rev(1, lx, ly, lx + 17, ly + 17);
fllast = SUB_oct_sub(m);
TIMER_set(20);
while (MOS_rdpos(&mb, &mx, &my), mb & 1) {
int whres;
whres = Where(mx, my) == (m ? WH_OCTM : WH_OCTP);
if (!whres && flpush || whres && !flpush) {
EGB_rev(1, lx, ly, lx + 17, ly + 17);
flpush = !flpush;
}
if (flpush && TIMER() && !fllast) {
fllast = SUB_oct_sub(m);
TIMER_set(20);
}
}
if (flpush)
EGB_rev(1, lx, ly, lx + 17, ly + 17);
}
static int SUB_oct_sub(int m) {
int result = 1;
if (m && Sub.oct > 1 || !m && Sub.oct < 8) {
m ? Sub.oct-- : Sub.oct++;
MOS_disp(0);
Draw_oct();
MOS_disp(1);
result = 0;
}
return result;
}
static void SUB_vol(int m) {
int flpush = 1, fllast, lx, ly;
int mx, my;
char mb;
lx = wx + (m ? 221 : 308);
ly = wy + 90;
EGB_rev(1, lx, ly, lx + 14, ly + 14);
fllast = SUB_vol_sub(m);
TIMER_set(20);
while (MOS_rdpos(&mb, &mx, &my), mb & 1) {
int whres;
whres = Where(mx, my) == (m ? WH_VOLM : WH_VOLP);
if (!whres && flpush || whres && !flpush) {
EGB_rev(1, lx, ly, lx + 14, ly + 14);
flpush = !flpush;
}
if (flpush && TIMER() && !fllast)
fllast = SUB_vol_sub(m);
}
if (flpush)
EGB_rev(1, lx, ly, lx + 14, ly + 14);
}
static int SUB_vol_sub(int m) {
int result = 1;
if (m && Sub.onryo > 0 || !m && Sub.onryo < 127) {
m ? Sub.onryo-- : Sub.onryo++;
MOS_disp(0);
Draw_volbar();
Draw_onryo();
MOS_disp(1);
result = 0;
}
return result;
}
static void SUB_voldr(int x, int y) {
int wh;
char mb;
if ((wh = Where_vol(x, y)) < 0)
return;
ICN_mos(3);
Sub.onryo = wh * 127 / 55;
MOS_disp(0);
Draw_volbar();
Draw_onryo();
MOS_disp(1);
while (MOS_rdpos(&mb, &x, &y), mb & 1) {
if ((wh = Where_vol(x, y)) < 0)
continue;
wh = wh * 127 / 55; /* NOT wh *= 127 / 55 */
if (wh != Sub.onryo) {
wh < Sub.onryo ? Sub.onryo-- : Sub.onryo++;
MOS_disp(0);
Draw_volbar();
Draw_onryo();
MOS_disp(1);
}
}
ICN_mos(0);
}
static int Where_vol(int x, int y) {
int ret;
if (Where(x, y) != WH_VOL) {
ret = -1;
} else {
ret = x - (wx + 244);
if (ret < 0)
ret = 0;
else if (ret > 55)
ret = 55;
}
return ret;
}
static int Settings(struct Par *p, char *path) {
FILE *fp;
free(p->data);
p->data = NULL;
if ((fp = fopen(path, "rb")) == NULL)
return 1;
if ((p->size = filelength(fileno(fp))) <= 32) {
fclose(fp);
return 2;
}
if ((p->data = malloc(p->size)) == NULL) {
fclose(fp);
return 3;
}
clearerr(fp);
fread(p->data, 1, p->size, fp);
if (ferror(fp) || feof(fp)) {
fclose(fp);
free(p->data);
p->data = NULL;
return 1;
}
if (p->size < *((unsigned long *)((char *)p->data + 12)) + 32) {
fclose(fp);
free(p->data);
p->data = NULL;
return 2;
}
fclose(fp);
p->ontei = *((unsigned char *)p->data + 28);
if (p->ontei < 24 || 119 < p->ontei) p->ontei = 60;
p->oct = (p->ontei - 24) / 12 + 1;
p->onryo = 127;
return 0;
}